package fun.werfamily.wf.order.core.domain.service.impl;

import fun.werfamily.wf.base.dto.LoginUserContext;
import fun.werfamily.wf.order.core.domain.dto.req.goods.GoodsSkuDTO;
import fun.werfamily.wf.order.core.domain.dto.result.CartItemDTO;
import fun.werfamily.wf.order.core.domain.dto.result.OrderGoodsCartDTO;
import fun.werfamily.wf.order.core.domain.enums.ResponseCodeEnum;
import fun.werfamily.wf.order.core.domain.exception.OrderCoreException;
import fun.werfamily.wf.order.core.domain.remote.facade.GoodsServiceFacade;
import fun.werfamily.wf.order.core.domain.service.OrderGoodsCartService;
import fun.werfamily.wf.order.core.infrastructure.dataobject.OrderGoodsCartDO;
import fun.werfamily.wf.order.core.infrastructure.mapper.OrderGoodsCartMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: Mr.WenMing Zhang
 * @Date: 2023-04-24 21:35
 * @Description:
 */
@Service
@Slf4j
public class OrderGoodsCartServiceImpl implements OrderGoodsCartService {

    @Resource
    private OrderGoodsCartMapper orderGoodsCartMapper;

    @Resource
    private GoodsServiceFacade goodsServiceFacade;

    @Override
    public OrderGoodsCartDTO getGoodsCartItem() {
        OrderGoodsCartDTO orderGoodsCartDTO = new OrderGoodsCartDTO();
        List<CartItemDTO> cartItemDTOS = new ArrayList<>();
        List<OrderGoodsCartDO> orderGoodsCartDOS = orderGoodsCartMapper.listByUserCode(LoginUserContext.getUserCode());
        if (CollectionUtils.isEmpty(orderGoodsCartDOS)) {
            return orderGoodsCartDTO;
        }
        List<String> skuCodes = orderGoodsCartDOS.stream().map(OrderGoodsCartDO::getSkuCode).collect(Collectors.toList());
        // 获取商品信息
        List<GoodsSkuDTO> goodsSkuDTOS = goodsServiceFacade.goodsSkuDetail(skuCodes);
        if (CollectionUtils.isEmpty(goodsSkuDTOS)) {
            return orderGoodsCartDTO;
        }
        Map<String, GoodsSkuDTO> goodsSkuDTOMap = goodsSkuDTOS.stream().collect(Collectors.toMap(GoodsSkuDTO::getSkuCode, Function.identity(), (o, n) -> n));
        for (OrderGoodsCartDO orderGoodsCartDO : orderGoodsCartDOS) {
            CartItemDTO cartItemDTO = new CartItemDTO();
            BeanUtils.copyProperties(orderGoodsCartDO, cartItemDTO);
            if (null != goodsSkuDTOMap.get(orderGoodsCartDO.getSkuCode())) {
                GoodsSkuDTO goodsSkuDTO = goodsSkuDTOMap.get(orderGoodsCartDO.getSkuCode());
                cartItemDTO.setSalesPrice(goodsSkuDTO.getSalesPrice());
                cartItemDTO.setSkuImg(goodsSkuDTO.getShortImage());
                cartItemDTO.setGoodsSpecValueDTOList(goodsSkuDTO.getGoodsSpecValueDTOList());
                //cartItemDTO.setStatus();
            }
            cartItemDTOS.add(cartItemDTO);
        }
        orderGoodsCartDTO.setItems(cartItemDTOS);
        orderGoodsCartDTO.setQuantity(cartItemDTOS.stream().mapToInt(CartItemDTO::getQuantity).sum());
        orderGoodsCartDTO.setTotalAmount(cartItemDTOS.stream().map(CartItemDTO::getSalesPrice).reduce(BigDecimal.ZERO, BigDecimal::add));
        return orderGoodsCartDTO;
    }

    @Override
    public Boolean addGoodsCartItem(CartItemDTO cartItemDTO) {
        String userCode = LoginUserContext.getUserCode();
        List<OrderGoodsCartDO> orderGoodsCartDOS = orderGoodsCartMapper.listByUserCode(userCode);
        if (!CollectionUtils.isEmpty(orderGoodsCartDOS)) {
            Set<String> cartItems = orderGoodsCartDOS.stream().map(OrderGoodsCartDO::getSkuCode).collect(Collectors.toSet());
            if (cartItems.contains(cartItemDTO.getSkuCode())) {
                orderGoodsCartMapper.addQuantityByUserCodeAndSkuCode(userCode, cartItemDTO.getSkuCode(), cartItemDTO.getQuantity());
                return Boolean.TRUE;
            }
        }
        List<GoodsSkuDTO> goodsSkuDTOS = goodsServiceFacade.goodsSkuDetail(Collections.singletonList(cartItemDTO.getSkuCode()));
        OrderGoodsCartDO orderGoodsCartDO = new OrderGoodsCartDO();
        orderGoodsCartDO.setQuantity(cartItemDTO.getQuantity());
        orderGoodsCartDO.setSkuCode(cartItemDTO.getSkuCode());
        orderGoodsCartDO.setUserCode(userCode);
        orderGoodsCartDO.setCreateBy(userCode);
        orderGoodsCartDO.setUpdateBy(userCode);
        orderGoodsCartDO.setUserCode(userCode);
        if (!CollectionUtils.isEmpty(goodsSkuDTOS)) {
            GoodsSkuDTO goodsSkuDTO = goodsSkuDTOS.get(0);
            orderGoodsCartDO.setSkuImg(goodsSkuDTO.getShortImage());
            orderGoodsCartDO.setSkuName(goodsSkuDTO.getSkuName());
            orderGoodsCartDO.setSpuCode(goodsSkuDTO.getSpuCode());
            orderGoodsCartDO.setSpuName(goodsSkuDTO.getSkuName());
        }
        orderGoodsCartMapper.insertSelective(orderGoodsCartDO);
        return Boolean.TRUE;
    }

    @Override
    public Boolean updateGoodsCartItem(CartItemDTO cartItemDTO) {
        String userCode = LoginUserContext.getUserCode();
        OrderGoodsCartDO orderGoodsCartDO = orderGoodsCartMapper.selectByUserCodeAndSkuCode(userCode, cartItemDTO.getSkuCode());
        if (null == orderGoodsCartDO) {
            throw new OrderCoreException(ResponseCodeEnum.ORDER_GOODS_CART_ITEM_NOT_EXIST);
        }
        orderGoodsCartMapper.updateQuantityByUserCodeAndSkuCode(userCode, cartItemDTO.getSkuCode(), cartItemDTO.getQuantity());
        return Boolean.TRUE;
    }

    @Override
    public Boolean removeGoodsCartItem(List<String> skuCodes) {
        String userCode = LoginUserContext.getUserCode();
        List<OrderGoodsCartDO> orderGoodsCartDOS = orderGoodsCartMapper.listByUserCode(userCode);
        if (!CollectionUtils.isEmpty(orderGoodsCartDOS)) {
            Set<String> cartItems = orderGoodsCartDOS.stream().map(OrderGoodsCartDO::getSkuCode).collect(Collectors.toSet());
            for (String skuCode : skuCodes) {
                if (!cartItems.contains(skuCode)) {
                    throw new OrderCoreException(ResponseCodeEnum.ORDER_GOODS_CART_ITEM_NOT_EXIST);
                }
            }
        }
        orderGoodsCartMapper.removeByUserCodeAndSkuCode(userCode, skuCodes);
        return Boolean.TRUE;
    }

    @Override
    public Boolean removeAllGoodsCartItem() {
        orderGoodsCartMapper.removeAllByUserCode(LoginUserContext.getUserCode());
        return Boolean.TRUE;
    }

    @Override
    public Integer countCartItems() {
        Integer itemCount = orderGoodsCartMapper.countCartItems(LoginUserContext.getUserCode());
        return itemCount == null ? 0 : itemCount;
    }
}
